<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of az_mysqli
 *
 * @author Shark
 */
class az_db extends mysqli {

    public function prepare($query) {
        return new az_stmt($this, $query);
    }

}

class az_stmt extends mysqli_stmt {

    public function __construct($link, $query) {
        $this->mbind_reset();
        parent::__construct($link, $query);
    }

    public function mbind_reset() {
        unset($this->mbind_params);
        unset($this->mbind_types);
        $this->mbind_params = array();
        $this->mbind_types = array();
    }

    //use this one to bind params by reference
    public function mbind_param($type, &$param) {
        $this->mbind_types[0].= $type;
        $this->mbind_params[] = &$param;
    }

    //use this one to bin value directly, can be mixed with mbind_param()
    public function mbind_value($type, $param) {
        $this->mbind_types[0].= $type;
        $this->mbind_params[] = $param;
    }

    public function mbind_param_do() {
        $params = array_merge($this->mbind_types, $this->mbind_params);
        return call_user_func_array(array($this, 'bind_param'), $this->makeValuesReferenced($params));
    }

    private function makeValuesReferenced($arr) {
        $refs = array();
        foreach ($arr as $key => $value)
            $refs[$key] = &$arr[$key];
        return $refs;
    }

    public function execute() {
        if (count($this->mbind_params))
            $this->mbind_param_do();

        return parent::execute();
    }

    private $mbind_types = array();
    private $mbind_params = array();

}

class Az_MysqliConnect {

    //Config system
    private $host = 'localhost';
    private $user = 'root';
    private $pass = '111';
    private $database = 'az_diemthi_24';
    //Check stt connect database
    public $stt;
    private $connect;

    /*
     * Construct function
     */
    public function __construct() {
        $this->connect = new az_db($this->host, $this->user, $this->pass, $this->database);
        if ($this->connect->connect_errno) {
            $this->stt = false;
        } else {
            $this->stt = true;
        }
    }

    //Return a connection
    public function getConnect() {
        return $this->connect;
    }

    //Close connection
    public function closeConnect() {
        if ($this->connect->close()) {
            return true;
        } else {
            return false;
        }
    }

    /*
     * Function to bind Parameters to run SQL statement with params is array
     */

    private function bindParameters(&$statement, &$params) {
        $args = array();
        $args[] = implode('', array_values($params));

        foreach ($params as $paramName => $paramType) {
            $args[] = &$params[$paramName];
            $params[$paramName] = null;
        }

        call_user_func_array(array(&$statement, 'bind_param'), $args);
    }

    /*
     *  Function execute sql for add, delete, update
     */

    public function executeStmt_Az($sql, $type, array $params) {
        if ($sql != null && $this->stt) {
            $query = $this->getConnect()->prepare($sql);
            $bind_names[] = $type;
            for ($i = 0; $i < count($params); $i++) {
                $bind_name = 'bind' . $i;
                $$bind_name = $params[$i];
                $bind_names[] = &$$bind_name;
            }
            call_user_func_array(array($query, 'bind_param'), $bind_names);
            if ($query->execute()) {
                $query->close();
                return true;
            } else {
                $query->close();
                return false;
            }
        }
    }

    public function executeStmt($sql, array $params) {
        if ($sql != null && $this->stt) {
            $query = $this->getConnect()->prepare($sql);
            $this->bindParameters($query, $params);
            if (!$query->execute()) {
                $query->close();
                return false;
            } else {
                $query->close();
                return true;
            }
        }
    }

    /*
     * Function execute by mysqli_query
     */
    public function executeSQL_Query($sql) {
        if ($sql != null) {
            $result = $this->getConnect()->query($sql);
            if($result){
                return $result;
            }else{
                return false;
            }
        }
    }

    /*
     *  Sql run query for get data
     * @return: Array of result or null
     *  
     */

    public function getData($sql, array $params) {
        if ($sql != null && $this->stt) {
            if (count($params) > 0) {
                $stmQuery = $this->getConnect()->prepare($sql);
                foreach ($params as $key => $value) {
                    $stmQuery->mbind_param('s', $value);
                }
                if ($stmQuery->execute()) {
                    $resutl = $stmQuery->get_result();
                    $stmQuery->close();
                    return $resutl;
                } else {
                    $stmQuery->close();
                    return null;
                }
            } else {
                $stmQuery = $this->getConnect()->prepare($query);
                if ($stmQuery->execute()) {
                    $result = $stmQuery->get_result();
                    $stmQuery->close();
                    return $result;
                } else {
                    $stmQuery->close();
                    return null;
                }
            }
        }
    }

    /*
     * Check avaliable in database
     */

    public function checkAvaliable($sql, array $params) {
        
    }

    /*
     * Call store prc
     */

    public function callStorePrc($storeName, array $params) {
        
    }

    /*
     * Call a function 
     */

    public function callFunction($functionName, array $params) {
        
    }

}

//Create a global object $az_db
$az_db = new Az_MysqliConnect();
?>
